﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ELO
{
    public partial class frmMain : Form
    {
        Data data;

        public frmMain()
        {
            InitializeComponent();
            data = new Data();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            this.LoadPlayers();
            this.txtGameDate.Text = DateTime.Now.ToShortDateString();
        }

        private void LoadPlayers()
        {
            Player[] players = data.GetPlayers();
            cmbPlayerWinner.DataSource = players.Clone();
            cmbPlayerLoser.DataSource = players.Clone();
            Player[] leaderboard = (from p in players
                                   orderby p.Rating descending
                                   select p).ToArray();
            lstPlayers.DataSource = leaderboard;

            cmbPlayerLoser.Text = "";
            cmbPlayerWinner.Text = "";
        }

        private void btnAddPlayer_Click(object sender, EventArgs e)
        {
            frmAddPlayer frm = new frmAddPlayer();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                Player p = new Player(frm.txtName.Text);
                data.AddPlayer(p);
                this.LoadPlayers();
            }
        }

        private void lstPlayers_SelectedValueChanged(object sender, EventArgs e)
        {
            Player selectedPlayer = (Player)this.lstPlayers.SelectedItem;

            this.lblInfoLosses.Text = selectedPlayer.Losses.ToString();
            this.lblInfoRating.Text = selectedPlayer.Rating.ToString();
            this.lblInfoWins.Text = selectedPlayer.Wins.ToString();

            Player[] players = data.GetPlayers();
            players = (from p in players
                      where p.ID != selectedPlayer.ID
                      select p).ToArray();
            this.cmbOwedTo.DataSource = players;
        }

        private void rbValueRegular_CheckedChanged(object sender, EventArgs e)
        {
            this.UpdateTotalGamePoints();
        }

        private void rbValueGammon_CheckedChanged(object sender, EventArgs e)
        {
            this.UpdateTotalGamePoints();
        }

        private void rbValueBackgammon_CheckedChanged(object sender, EventArgs e)
        {
            this.UpdateTotalGamePoints();
        }

        private void UpdateTotalGamePoints()
        {
            int multiplier = 1;
            if (rbValueGammon.Checked) multiplier = 2;
            if (rbValueBackgammon.Checked) multiplier = 3;

            try
            {
                int points = Int32.Parse(this.txtPoints.Text);
                int totalPoints = points * multiplier;
                this.lblGameValue.Text = totalPoints.ToString();
                double moneyPerPoint = Double.Parse(this.txtMoneyPerPoint.Text);
                this.lblMoneyValue.Text = "$" + (moneyPerPoint * totalPoints).ToString("######0.00");
            }
            catch
            {
                this.lblGameValue.Text = multiplier.ToString();
                this.lblMoneyValue.Text = "$0.00";
            }

        }

        private void btnRecord_Click(object sender, EventArgs e)
        {
            this.UpdateTotalGamePoints();
            int gameValue = Int32.Parse(this.txtPoints.Text);
            if (!powerOf2(gameValue))
            {
                MessageBox.Show("The Points field must be a power of 2.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            if (cmbPlayerWinner.SelectedItem == null || cmbPlayerLoser.SelectedItem == null || txtGameDate.Text == "")
            {
                MessageBox.Show("Please fill in all the game information.", "Missing Info", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            if (((Player)cmbPlayerWinner.SelectedItem).ID == ((Player)cmbPlayerLoser.SelectedItem).ID)
            {
                MessageBox.Show("Please select two different players.", "Duplicate Player", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            Game g = new Game();
            g.Backgammon = this.rbValueBackgammon.Checked ? 1 : 0;
            g.GameDate = DateTime.Parse(this.txtGameDate.Text);
            g.Gammon = this.rbValueGammon.Checked ? 1 : 0;
            g.Loser = ((Player)this.cmbPlayerLoser.SelectedItem).ID;
            g.TotalPoints = Int32.Parse(this.lblGameValue.Text);
            g.Winner = ((Player)this.cmbPlayerWinner.SelectedItem).ID;
            g.TotalMoney = float.Parse(this.lblMoneyValue.Text.Substring(1));

            Player winnerOldData= data.GetPlayer(g.Winner);
            Player loserOldData = data.GetPlayer(g.Loser);

            data.AddGame(g);
            this.LoadPlayers();

            Player winnerNewData = data.GetPlayer(g.Winner);
            Player loserNewData = data.GetPlayer(g.Loser);

            MessageBox.Show(
                String.Format("{0} {1} -> {2}\r\n{3} {4} -> {5}", 
                    winnerOldData.Name, winnerOldData.Rating.ToString(), winnerNewData.Rating.ToString(), loserOldData.Name, loserOldData.Rating.ToString(), loserNewData.Rating.ToString()), 
                "New Ratings", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private bool powerOf2(long number)
        {
            if (number < 1)
            {
                return false;
            }
            if (number == 1)
            {
                return true;
            }
            if ((number & 1) == 1)
            {
                return false;
            }
            return powerOf2(number >> 1);
        }

        private void txtPoints_TextChanged(object sender, EventArgs e)
        {
            this.UpdateTotalGamePoints();
        }

        private void txtMoneyPerPoint_TextChanged(object sender, EventArgs e)
        {
            this.UpdateTotalGamePoints();
        }

        private void cmbOwedTo_SelectedValueChanged(object sender, EventArgs e)
        {
            double amount = data.GetAmountOwed(((Player)this.lstPlayers.SelectedItem).ID, ((Player)this.cmbOwedTo.SelectedItem).ID);
            this.lblOwed.Text = amount.ToString("$######0.00");
        }

        private void btnRecordPayment_Click(object sender, EventArgs e)
        {
            frmPayment frm = new frmPayment();
            frm.lblPayee.Text = ((Player)this.cmbOwedTo.SelectedItem).DisplayValue;
            frm.lblPayer.Text = ((Player)this.lstPlayers.SelectedItem).DisplayValue;
            frm.txtAmount.Text = "0.00";
            frm.txtDate.Text = DateTime.Now.ToShortDateString();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                data.RecordPayment(
                    ((Player)this.lstPlayers.SelectedItem).ID, 
                    ((Player)this.cmbOwedTo.SelectedItem).ID, 
                    Double.Parse(frm.txtAmount.Text), 
                    DateTime.Parse(frm.txtDate.Text));
            }
        }

        private void btnRecalc_Click(object sender, EventArgs e)
        {
            if (DialogResult.Yes == MessageBox.Show(
                    "It may take a while to recalculate all the rankings.\r\nAre you sure you want to continue?", "Recalculate Rankings", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
            {
                data.RecalculateAllRatings();
            }
        }

    }
}
